package com.fr.data.impl;

import com.fr.base.ArrayUtils;
import com.fr.base.FRContext;
import com.fr.base.Inter;
import com.fr.base.StringUtils;
import com.fr.data.TableDataException;
import com.fr.data.core.DataUtils;
import com.fr.data.core.db.ColumnInformation;
import com.fr.data.core.db.DBUtils;
import com.fr.data.core.db.dialect.Dialect;
import com.fr.data.core.db.dialect.DialectFactory;
import com.fr.report.core.ParameterHelper;
import com.fr.report.parameter.Parameter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class LayerPageQueryAdapter extends TableDataAdapter
{
  private static final long serialVersionUID = 1L;
  public static final String STARTROW_IDENTIFIER = "fr_startrow";
  public static final String PAGESIZE_IDENTIFIER = "fr_pagesize";
  public static final String PAGE_NUMBER_IDENTIFIER = "fr_pagenumber";
  public static final String ROW_COUNT_IDENTIFIER = "fr_rowcount";
  private transient int startRow;
  private int pageSize;
  private transient int currentRowIndex = -1;
  private transient Object[] currentRowValue = null;
  private String rowCountQuery = null;
  protected String pageQuery;
  private boolean bePaged = false;
  private String originalQuery;
  private Parameter[] parameters;

  public LayerPageQueryAdapter(DatabaseConnection paramDatabaseConnection, String paramString1, String paramString2, Parameter[] paramArrayOfParameter, int paramInt)
  {
    super(paramDatabaseConnection, paramString1, 0);
    this.originalQuery = paramString1;
    this.pageSize = paramInt;
    this.pageQuery = paramString2;
    this.parameters = paramArrayOfParameter;
  }

  public int getRowCount()
    throws TableDataException
  {
    return shortcutGetRowCount();
  }

  protected int shortcutGetRowCount()
  {
    if (this.shortcutRowCount == -1)
    {
      long l1 = System.currentTimeMillis();
      String str = this.rowCountQuery;
      if ((str == null) && (DBUtils.isProcedure(this.sql)))
      {
        this.shortcutRowCount = -2147483648;
        FRContext.getLogger().log(Level.WARNING, Inter.getLocText("DBTableData_Not_Get_RowCount"));
        throw new RuntimeException(Inter.getLocText("DBTableData_Not_Get_RowCount"));
      }
      Connection localConnection = null;
      try
      {
        localConnection = this.database.createConnection();
        if (this.dialect == null)
          this.dialect = DialectFactory.generateDialect(localConnection);
        if (str == null)
          str = this.dialect.getCountSql(this.sql);
        FRContext.getLogger().log(Level.INFO, "RowCount SQL:\n" + str);
        Statement localStatement = localConnection.createStatement();
        ResultSet localResultSet = localStatement.executeQuery(str);
        localResultSet.next();
        this.shortcutRowCount = localResultSet.getInt(1);
        localResultSet.close();
        localStatement.close();
      }
      catch (Exception localException)
      {
        this.shortcutRowCount = -2147483648;
        throw new RuntimeException(localException.getMessage());
      }
      finally
      {
        if (localConnection != null)
          try
          {
            localConnection.close();
          }
          catch (SQLException localSQLException)
          {
            FRContext.getLogger().log(Level.WARNING, localSQLException.getMessage(), localSQLException);
          }
      }
      long l2 = System.currentTimeMillis();
      FRContext.getLogger().log(Level.INFO, "RowCount costs " + ((l2 - l1) / 1000L) + " s.");
    }
    return this.shortcutRowCount;
  }

  public Object getValueAt(int paramInt1, int paramInt2)
    throws TableDataException
  {
    return ((hasRow(paramInt1)) ? this.currentRowValue[paramInt2] : null);
  }

  protected boolean hasRow(int paramInt)
    throws TableDataException
  {
    int i = paramInt - this.startRow;
    if (paramInt < 0)
      return false;
    if (i == this.currentRowIndex)
      return true;
    if ((!(this.bePaged)) || (i < this.currentRowIndex) || (i >= this.pageSize))
    {
      try
      {
        releaseConnection();
      }
      catch (SQLException localSQLException1)
      {
        this.connection = null;
        this.statement = null;
        this.resultSet = null;
        FRContext.getLogger().log(Level.WARNING, localSQLException1.getMessage(), localSQLException1);
      }
      createPageQuery(paramInt);
      this.isCheckRowOver = false;
      this.bePaged = true;
    }
    else if (this.isCheckRowOver)
    {
      return false;
    }
    initConnectionAndResultAndCheckInColumns();
    if (this.connection == null)
      return false;
    Dialect localDialect = DialectFactory.generateDialect(this.connection);
    int j = getColumnCount();
    int k = 0;
    try
    {
      String str1 = this.database.getOriginalCharsetName();
      String str2 = this.database.getNewCharsetName();
      do
      {
        if (!(this.resultSet.next()))
          break label316;
        this.currentRowIndex += 1;
      }
      while (this.currentRowIndex < paramInt - this.startRow);
      this.currentRowValue = new Object[j];
      for (int l = 0; l < j; ++l)
        try
        {
          this.currentRowValue[l] = DataUtils.getResultSetObject(this.resultSet, this.columnInformations[l].getColumnType(), l + 1, str1, str2, localDialect);
        }
        catch (SQLException localSQLException2)
        {
          FRContext.getLogger().log(Level.WARNING, localSQLException2.getMessage(), localSQLException2);
        }
      if ((this.currentRowIndex == this.pageSize - 1) || (this.currentRowIndex + this.startRow == this.shortcutRowCount - 1))
        k = 1;
      else
        return true;
      label316: this.isCheckRowOver = true;
      releaseConnection();
    }
    catch (Exception localException1)
    {
      try
      {
        releaseConnection();
      }
      catch (Exception localException2)
      {
      }
      this.isCheckRowOver = true;
      throw new TableDataException(localException1.getMessage() + "\nQuery is:" + this.sql + "\nrowIndex to get is:" + paramInt, localException1);
    }
    return k;
  }

  protected void initRowValueStatus()
  {
    this.currentRowIndex = -1;
    this.currentRowValue = null;
  }

  protected boolean createPageQuery(int paramInt)
  {
    if (StringUtils.isBlank(this.pageQuery))
    {
      if (this.dialect.supportsLimitOffset())
      {
        this.sql = this.dialect.getLimitString(this.originalQuery, paramInt, this.pageSize);
        this.startRow = paramInt;
        break label270:
      }
      this.sql = this.originalQuery;
      FRContext.getLogger().log(Level.WARNING, Inter.getLocText("LayerPageReport_PageQuery_Unsupport_Msg1") + "!");
      return false;
    }
    this.startRow = paramInt;
    ArrayList localArrayList = new ArrayList();
    if (!(ArrayUtils.isEmpty(this.parameters)))
      localArrayList.addAll(Arrays.asList(this.parameters));
    localArrayList.add(new Parameter("fr_startrow", new Integer(this.startRow)));
    localArrayList.add(new Parameter("fr_pagesize", new Integer(this.pageSize)));
    localArrayList.add(new Parameter("fr_pagenumber", new Integer(this.startRow / this.pageSize + 1)));
    localArrayList.add(new Parameter("fr_rowcount", new Integer(this.shortcutRowCount)));
    this.sql = ParameterHelper.analyze4Templatee(this.pageQuery, (Parameter[])localArrayList.toArray(new Parameter[0]));
    label270: return true;
  }
}